package luccy.desc.impl;

import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.util.ArrayList;
import java.util.List;

import luccy.desc.AnnotationDesc;
import luccy.desc.Desc;
import luccy.util.AssertionUtil;

public class AnnotationDescImpl implements AnnotationDesc {

	private Desc annotatedDesc;

	private Annotation annotation;

	private ElementType type;

	private String annotationName;

	private List<Class<? extends Annotation>> metaAnnotationClassList;

	private Class<? extends Annotation> annotationType;

	public AnnotationDescImpl(Desc desc, Annotation annotation, ElementType type) {
		AssertionUtil.assertNotNull(desc);
		AssertionUtil.assertNotNull(annotation);
		AssertionUtil.assertNotNull(type);
		this.annotatedDesc = desc;
		this.annotation = annotation;
		this.metaAnnotationClassList = new ArrayList<Class<? extends Annotation>>();
		for (Annotation a : annotation.annotationType().getAnnotations()) {
			final String canonicalName = a.annotationType().getCanonicalName();
			if(!canonicalName.startsWith("java.lang")) {
				metaAnnotationClassList.add(a.annotationType());
			}
		}
		this.type = type;
		this.annotationName = annotation.getClass().getSimpleName();
		this.annotationType = annotation.annotationType();
	}

	public Annotation getAnnotation() {
		return annotation;
	}

	public String getAnnotationName() {
		return annotationName;
	}

	public Class<? extends Annotation> getAnnotationType() {
		return annotationType;
	}

	public ElementType getType() {
		return type;
	}

	public Desc getAnnotatedDesc() {
		return annotatedDesc;
	}

	public List<Class<? extends Annotation>> getMetaAnnotationClassList() {
		return metaAnnotationClassList;
	}

	public boolean hasMetaAnnotation(Class<? extends Annotation> metaAnnotation) {
		return metaAnnotationClassList.contains(metaAnnotation);
	}

}
